#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2017, Fabian Greif
# Copyright (c) 2017-2018, Niklas Hauser
#
# This file is part of the modm project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------

def get_properties(env):
    device = env[":target"]
    driver = device.get_driver("usart:avr")
    properties = device.properties
    properties["target"] = device.identifier
    properties["driver"] = driver
    return properties

def load_options(module):
    module.add_option(
        NumericOption(
            name="buffer.tx",
            description="",
            minimum=1, maximum=254,
            default=64))
    module.add_option(
        NumericOption(
            name="buffer.rx",
            description="",
            minimum=1, maximum=254,
            default=8))

class Instance(Module):
    def __init__(self, instance):
        self.instance = instance

    def init(self, module):
        module.name = str(self.instance)
        module.description = "Instance {}".format(self.instance)

    def prepare(self, module, options):
        module.depends(":platform:uart")
        load_options(module)
        return True

    def build(self, env):
        properties = get_properties(env)
        target = properties["target"]

        if target["family"] == "tiny" and target["name"] in ["828", "2313", "4313"]:
            instance = ""
        else:
            instance = self.instance
        properties["id"] = instance

        env.substitutions = properties
        env.outbasepath = "modm/src/modm/platform/uart"

        env.template("uart.hpp.in", "uart{}.hpp".format(instance))
        env.template("uart_tx.cpp.in", "uart{}_tx.cpp".format(instance))
        env.template("uart_rx.cpp.in", "uart{}_rx.cpp".format(instance))


def init(module):
    module.name = ":platform:uart"
    module.description = "Universal Asynchronous Receiver Transmitter (UART)"

def prepare(module, options):
    device = options[":target"]
    if not device.has_driver("usart:avr"):
        return False

    module.depends(
        ":architecture:atomic",
        ":architecture:interrupt",
        ":architecture:uart",
        ":math:algorithm",
        ":platform:gpio")

    driver = device.get_driver("usart:avr")
    if "instance" in driver:
        for instance in listify(driver["instance"]):
            module.add_submodule(Instance(int(instance)))
    else:
        load_options(module)

    return True

def build(env):
    properties = get_properties(env)
    driver = properties["driver"]

    if "instance" not in driver:
        properties["id"] = ""

    env.substitutions = properties
    env.outbasepath = "modm/src/modm/platform/uart"

    env.template("uart_defines.h")

    if "instance" not in driver:
        env.template("uart.hpp.in")
        env.template("uart_tx.cpp.in")
        env.template("uart_rx.cpp.in")
